# coding=utf8
import json

import falcon
from bs4 import BeautifulSoup
from bson import ObjectId
from libs import config
from libs.help import stream_to_params, get_root_path, md5sum
from libs.wx import add_img_for_long, add_news_for_long, get_resource
from models.resource.media import model_res_media
from models.resource.crawl import model_res_crawl
from models.resource.edited import model_res_edited
from models.resource.uploaded import model_res_uploaded
from models.user.ad import model_user_ad
from models.user.wx import model_user_wx
from logging import getLogger

logger = getLogger('base')

data_path = get_root_path('data/training')
statics_path = get_root_path('statics')
img_server = config['ImageServer']['host']


# 获取list的
class NewsResource:
    def on_options(self, req, resp, cid):
        resp.status = falcon.HTTP_200  # This is the default status
        resp.set_header('Access-Control-Allow-Origin', '*')
        resp.set_header('Access-Control-Allow-Headers', 'uid')
        resp.set_header('Access-Control-Allow-Methods', 'POST,GET')

    def on_get(self, req, resp, cid):
        where = {
            'ClassifyId': ObjectId(cid)
        }
        result = {
            'classify_name': '',
            'items': []
        }
        for item in model_res_crawl.get_list(80, where=where):
            res = {
                'title': item['Title'],
                'time_str': item['TimeStr'],
                'id': str(item['_id'])
            }
            if 'Edited' in item:
                res['status'] = True
            else:
                res['status'] = False
            result['items'].append(res)
            result['classify_name'] = item['ClassifyName']
        resp.status = falcon.HTTP_200  # This is the default status
        resp.set_header('Access-Control-Allow-Origin', '*')
        resp.set_header('Access-Control-Allow-Headers', 'uid')
        resp.body = json.dumps({
            'info': {
                'code': 200
            },
            'item': result
        })


class NewsContentResource:
    def on_options(self, req, resp, aid):
        resp.status = falcon.HTTP_200  # This is the default status
        resp.set_header('Access-Control-Allow-Origin', '*')
        resp.set_header('Access-Control-Allow-Headers', 'uid')
        resp.set_header('Access-Control-Allow-Methods', 'POST,GET')

    def on_get(self, req, resp, aid):
        data = model_res_crawl.coll.find_one({
            '_id': ObjectId(aid)
        })
        resp.set_header('Access-Control-Allow-Origin', '*')
        resp.set_header('Access-Control-Allow-Headers', 'uid')
        resp.body = json.dumps({
            'info': {
                'code': 200
            },
            'item': {
                'title': data['Title'],
                'content': data['Content']
            }
        })

    def on_post(self, req, resp, aid):
        data = req.stream.read().decode()
        data = stream_to_params(data)
        # todo 把新的扔到新库里去
        # if model_res_edited.coll.find_one({'OldId': ObjectId(aid)}) is None:
        #    model_res_edited.coll.insert_one({
        #        'OldId': ObjectId(aid),
        #        'Content': data['content'],
        #        'Source': data['Source']
        #    })

        if data['ad'] != '':
            soup = BeautifulSoup(data['ad'], 'lxml')
            for img in soup.find_all('img'):
                img_path = statics_path + img['src'].replace(img_server + '/', '')
                with open(data_path + 'ImgCollection.txt', 'a', encoding='utf8') as f:
                    f.write("\n")
                    f.write(md5sum(img_path) + "\n")
            ad_words = soup.get_text(strip=True)
            if ad_words != '':
                with open(data_path + 'AdCollection.txt', 'a', encoding='utf8') as f:
                    f.write("\n")
                    f.write("spam::" + ad_words)

        model_res_crawl.coll.update({'_id': ObjectId(aid)}, {
            '$set': {
                'Edited': True,
                'Content': data['content'],
                'Title': data['title']
            }
        })
        resp.status = falcon.HTTP_200  # This is the default status
        resp.set_header('Access-Control-Allow-Origin', '*')
        resp.set_header('Access-Control-Allow-Methods', 'POST')
        resp.set_header('Access-Control-Allow-Headers', 'uid')
        resp.body = json.dumps({
            'info': {
                'code': 200
            }
        })


img_server = config['ImageServer']['host']


def correct_article_content(content):
    soup = BeautifulSoup(content, 'lxml')
    image = soup.find('img')
    src = image['src'].replace(img_server + '/upload_image/', '').split('/')[1:]
    media_id = ObjectId(src[0])
    media = model_res_media.coll.find_one({'_id': media_id})

    for idx, img in enumerate(soup.find_all('img')):
        img['src'] = media['Source'][idx]

    return str(soup.body).replace("<body>", "").replace("</body>", "")


class NewsRemoteResource:
    def on_options(self, req, resp, appid):
        resp.status = falcon.HTTP_200  # This is the default status
        resp.set_header('Access-Control-Allow-Origin', '*')
        resp.set_header('Access-Control-Allow-Headers', 'uid')
        resp.set_header('Access-Control-Allow-Methods', 'POST,GET')

    def on_post(self, req, resp, appid):
        data = req.stream.read().decode()
        data = stream_to_params(data)
        uid = req.get_header('uid')

        if len(data['news_ids']) > model_user_wx.get_left(appid):
            resp.status = falcon.HTTP_200  # This is the default status
            resp.set_header('Access-Control-Allow-Origin', '*')
            resp.set_header('Access-Control-Allow-Methods', 'POST')
            resp.set_header('Access-Control-Allow-Headers', 'uid')
            resp.body = json.dumps({
                'info': {
                    'code': 500,
                    'codeMessage': '出错'
                }
            })
        else:
            news_ids = list(map(ObjectId, data['news_ids']))

            wx_info = model_user_wx.get(appid)
            # todo 需要过滤,检查是否已经发过
            items = model_res_crawl.coll.find({
                '_id': {
                    '$in': news_ids
                }
            })
            # todo 先检测有没有发过

            ad = model_user_ad.coll.find_one({
                'ClassifyId': ObjectId(data['cid']),
                'appid': appid
            })
            if ad is not None:
                ad_content = ad['Content']
            else:
                ad_content = ''

            for item in items:
                # 处理,然后一篇篇上传
                # todo 广告插前插后..
                content = correct_article_content(item['Content']) + "\n" + ad_content

                content = {
                    "articles": [{
                        'title': item['Title'],
                        'thumb_media_id': add_img_for_long(wx_info.wechat, item['Thumb']),
                        'author': wx_info.name,
                        'digest': '',
                        'show_cover_pic': 1,
                        'content': content,
                        'content_source_url': item['Url']  # todo 考虑取消这个..
                    }]
                }
                media_id = add_news_for_long(wx_info.wechat, content)
                logger.info("media id :" + media_id)

                news_source = get_resource(wx_info.wechat, media_id)
                news_item = news_source['news_item'][0]

                model_res_uploaded.coll.insert_one({
                    'Title': item['Title'],
                    'MediaId': media_id,
                    'appid': appid,
                    'Url': news_item['url'],
                    'Picurl': news_item['thumb_url']
                })
            model_user_wx.update_left(appid, len(news_ids))
            resp.status = falcon.HTTP_200  # This is the default status
            resp.set_header('Access-Control-Allow-Origin', '*')
            resp.set_header('Access-Control-Allow-Methods', 'POST')
            resp.set_header('Access-Control-Allow-Headers', 'uid')
            resp.body = json.dumps({
                'info': {
                    'code': 200
                }
            })
